package cn.smile.business.core.impl;

import cn.smile.business.core.IWebsiteService;
import cn.smile.commons.constant.NumberConstant;
import cn.smile.commons.exceptions.BusinessException;
import cn.smile.commons.response.MyResponseCode;
import com.alibaba.fastjson2.JSON;
import com.aliyun.alidns20150109.Client;
import com.aliyun.alidns20150109.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class WebsiteServiceImpl implements IWebsiteService {
    @Value("${ali.endpoint}")
    private String endpoint;

    @Override
    public Boolean changeDns(String ip, String hostname, String accessKey, String secretKey) {
        Client client = this.getClient(accessKey, secretKey);
        try {
            ArrayList<String> hostNameList = Lists.newArrayList(hostname.split("\\."));
            String keyWord = "";
            if (hostNameList.size() >= NumberConstant.THREE) {
                keyWord = hostNameList.get(NumberConstant.ZERO);
                hostNameList.remove(NumberConstant.ZERO);
            }
            String domain = String.join(".", hostNameList);
            //获取解析记录
            DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord domainDnsRecord = this.getDomainDnsRecord(client, domain, keyWord);
            // 刷新解析记录
            this.updateDomainDnsRecord(client, domainDnsRecord, ip);
        } catch (Exception e) {
            throw new BusinessException(MyResponseCode.A_LI_YUN_CHANGE_ERROR);
        }

        return Boolean.TRUE;
    }

    private void updateDomainDnsRecord(Client client, DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord domainDnsRecord, String newIp) throws Exception {
        if (!Objects.equals(domainDnsRecord.getValue(), newIp)) {
            // 修改记录
            UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest()
                    .setRecordId(domainDnsRecord.getRecordId())
                    .setRR(domainDnsRecord.getRR())
                    .setType(domainDnsRecord.getType())
                    .setValue(newIp);
            UpdateDomainRecordResponse updateDomainRecordResponse = client.updateDomainRecord(updateDomainRecordRequest);
            log.info("修改解析结果：{}", JSON.toJSONString(updateDomainRecordResponse));
        }
    }

    /**
     * 获取当前解析记录
     *
     * @param client  操作client对象
     * @param domain  域名
     * @param keyWord 三级域名
     * @return 当前解析记录
     * @throws Exception 异常信息
     */
    private DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord getDomainDnsRecord(Client client, String domain, String keyWord) throws Exception {
        DescribeDomainRecordsRequest describeDomainRecordsRequest = new DescribeDomainRecordsRequest()
                .setDomainName(domain)
                .setKeyWord(keyWord);
        DescribeDomainRecordsResponse domainRecordsResponse = client.describeDomainRecords(describeDomainRecordsRequest);
        List<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord> record = domainRecordsResponse.getBody().getDomainRecords().getRecord();
        DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord describeDomainRecordsResponseBodyDomainRecordsRecord = record.get(0);
        log.info("获取解析记录：{}", JSON.toJSONString(describeDomainRecordsResponseBodyDomainRecordsRecord));
        return describeDomainRecordsResponseBodyDomainRecordsRecord;
    }

    /**
     * 获取阿里云操作Client
     *
     * @param accessKey access
     * @param secretKey secret
     * @return 操作的client
     */
    private Client getClient(String accessKey, String secretKey) {
        Client client;
        try {
            client = new Client(new Config()
                    // 您的AccessKey ID
                    .setAccessKeyId(accessKey)
                    // 您的AccessKey Secret
                    .setAccessKeySecret(secretKey)
                    .setEndpoint(endpoint));
        } catch (Exception e) {
            throw new BusinessException(MyResponseCode.A_LI_YUN_CLIENT_ERROR);
        }
        return client;
    }
}
